package com.credit.mola.app.utils.http

import android.os.Handler
import android.os.Looper
import com.credit.mola.app.BuildConfig
import com.credit.mola.app.utils.config.Configs
import com.credit.mola.app.utils.event.track.TrackEventManager
import com.credit.mola.app.utils.log.HHLog
import com.credit.mola.app.utils.log.JsonFormat
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import okio.IOException
import org.json.JSONObject
import java.io.File
import java.util.concurrent.TimeUnit


/**
 * Sikadwa
 *
 * @Author wwdeng
 * @CreateTime: 2024/5/20 18:04
 * @Annotation：
 */
class OkHttpLoader : IHttpLoader {
    private var mHandler: Handler? = null  // 主线程Handler
    private var mOkHttpClient: OkHttpClient? = null

    init {
        mHandler = Handler(Looper.getMainLooper())
        val loggingInterceptor = HttpLoggingInterceptor()
        // 包含header、body数据
        if (BuildConfig.isDebug){
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
        } else {
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE)
        }
        // 创建OkHttpClient实例
        mOkHttpClient = OkHttpClient.Builder()
            .readTimeout(30000, TimeUnit.MILLISECONDS) // 设置读取超时时间
            .connectTimeout(30000, TimeUnit.MILLISECONDS) // 设置连接超时时间
            .writeTimeout(30000, TimeUnit.MILLISECONDS) // 设置写入超时时间
            .retryOnConnectionFailure(true) // 设置失败重试
            .addInterceptor(CommonHeaderInterceptor())//设置通用Header拦截器
            .addInterceptor(loggingInterceptor)
            .build()
    }

    /**
     * get
     */
    override fun get(url: String, callback: IHttpCallback) {
        val request: Request = Request.Builder().url(url).get().build()
        onRequestAction(request,callback)
    }

    /**
     * post
     */
    override fun post(url: String, params: JSONObject, callback: IHttpCallback) {
        val aesParams = AESCryptUtil.encryptDefault(params.toString())
        HHLog.e("HttpUrl：  $url")
        HHLog.e("HttpParams： $params")
        HHLog.e("HttpParams AES：  $aesParams")
        val requestBody = aesParams.toRequestBody("text/plain;charset=utf-8".toMediaTypeOrNull())
        val request = Request.Builder()
            .post(requestBody)
            .url(url)
            .build()
        onRequestAction(request,callback)
    }

    /**
     * 添加埋点
     */
    override fun addEvent(eventName: String, remark: String?) {
        var eventType = eventName.uppercase()//转大写
        if(!eventType.startsWith("${Configs.AppName}_")){
            eventType = "${Configs.AppName}_$eventType"
        }
        TrackEventManager.trackEvent(eventType,remark)

//        val httpUrl = AppUrls.getHttpUrl(AppUrls.URL.COMMON)
//        val params = JSONObject().addCommonParams().apply {
//            put("path", AppUrls.PATH.TRACK_EVENT)
//            put("type",eventType)//事件类型
//            put("remark",remark)//事件备注
//        }
//        val aesParams = AESCryptUtil.encryptDefault(params.toString())
//        HHLog.e("event url：  $httpUrl")
//        HHLog.e("event params： $params")
//        HHLog.e("event params aes：  $aesParams")
//        val requestBody = aesParams.toRequestBody("text/plain;charset=utf-8".toMediaTypeOrNull())
//        val request = Request.Builder()
//            .post(requestBody)
//            .url(httpUrl)
//            .build()
//        mOkHttpClient?.newCall(request)?.enqueue(object : Callback {
//            override fun onFailure(call: Call, e: IOException) {
//            }
//            override fun onResponse(call: Call, response: Response) {
//            }
//        })
    }

    /**
     * post upload file
     */
    override fun uploadFile(url: String, file: File, callback: IHttpCallback) {
        val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
        val filePart = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
        // 创建分段内容的建造器对象
        val builder = MultipartBody.Builder()
        val mediaType = "multipart/form-data".toMediaTypeOrNull()
        mediaType?.let {
            builder.setType(it)
        }
        builder.addPart(filePart)
        val requestBody = builder.build() // 根据建造器生成请求结构
        val request = Request.Builder()
            .post(requestBody)
            .url(url)
            .build()
        onRequestAction(request,callback,false)
    }

    private fun onRequestAction(request: Request,callback: IHttpCallback,isAES: Boolean=true){
        mOkHttpClient?.newCall(request)?.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                mHandler?.post {
                    callback.onRequestFinish()
                    val errorObj = JSONObject()
                    errorObj.put("errorCode",-1)
                    errorObj.put("errorMsg",e.message)
                    callback.onRequestError(errorObj)
                }
            }
            override fun onResponse(call: Call, response: Response) {
                mHandler?.post {
                    callback.onRequestFinish()
                }
                if (response.isSuccessful) {
                    if (response.code == 200){
                        response.body?.string()?.let {
                            var result = it
                            //需要解密
                            if (isAES){
                                result = AESCryptUtil.decryptDefault(it)
                            }
                            Thread {
                                HHLog.i("data：" + JsonFormat.format(result))
                            }.start()
                            mHandler?.post {
                                if (result.isNotEmpty()){
                                    callback.onRequestSuccess(JSONObject(result))
                                } else {
                                    val errorObj = JSONObject()
                                    errorObj.put("errorCode",response.code)
                                    errorObj.put("errorMsg",response.message)
                                    callback.onRequestError(errorObj)
                                }
                            }
                        }
                    } else {
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",response.code)
                        errorObj.put("errorMsg",response.message)
                        mHandler?.post { callback.onRequestError(errorObj) }
                    }
                } else {
                    mHandler?.post {
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",response.code)
                        errorObj.put("errorMsg",response.message)
                        callback.onRequestError(errorObj)
                    }
                }
            }
        })
    }
}
